package com.shiloop.flashlight;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Scroller;

/**
 * Created by skiloop on 2014/9/5.
 */
public class FlashFrameLayout extends FrameLayout {
    private static final String TAG = "FlashFrameLayout";
    private static final int SNAP_VELOCITY = 600;

    private VelocityTracker mVelocityTracker;
    private Scroller mScroller;

    private final int mDefaultScreen = 0;
    private int mCurrentScreen;

    private float mLastMotionX;

    private OnViewChangeListener mOnViewChangeListener;

    private boolean mIsLocked;

    public FlashFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mCurrentScreen = mDefaultScreen;
        mScroller = new Scroller(context);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        Log.d(TAG, "onLayout");
        if (changed) {
            int childLeft = 0;
            final int childCount = getChildCount();
            Log.e("childCount", "" + childCount);
            for (int i = 0; i < childCount; i++) {
                final View childView = getChildAt(i);
                if (childView.getVisibility() != View.GONE) {
                    final int childWidth = childView.getMeasuredWidth();
                    childView.layout(childLeft, 0, childLeft + childWidth,
                            childView.getMeasuredHeight());
                    childLeft += childWidth;
                }
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        Log.e("b", "b");
        final int width = MeasureSpec.getSize(widthMeasureSpec);

        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
        }
        scrollTo(mCurrentScreen * width, 0);
    }

    public void snapXBack() {
        Log.d(TAG, "snap x back");
        final int screenWidth = getWidth();

        final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth;
        snapToScreen(destScreen);
    }

    //使屏幕移动到第whichScreen+1屏
    public void snapToScreen(int whichScreen) {
        Log.d(TAG, "snapToScreen");
        if (getScrollX() != (whichScreen * getWidth())) {
            Log.d(TAG, "snap Screen");
            final int deltaX = whichScreen * getWidth() - getScrollX();
            mScroller.startScroll(getScrollX(), 0, deltaX, 0,
                    Math.abs(deltaX) * 2);
            mCurrentScreen = whichScreen;
            invalidate();
        }
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();

            if (mOnViewChangeListener != null) {
                mOnViewChangeListener.onViewChange(mCurrentScreen);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!mIsLocked) {
            final int action = event.getAction();
            final float x = event.getX();

            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    Log.i(TAG, "onTouchEvent  ACTION_DOWN");
                    if (mVelocityTracker == null) {
                        mVelocityTracker = VelocityTracker.obtain();
                        mVelocityTracker.addMovement(event);
                    }
                    if (!mScroller.isFinished()) {
                        mScroller.abortAnimation();
                    }
                    mLastMotionX = x;
                    break;

                case MotionEvent.ACTION_MOVE:
                    float deltaX = mLastMotionX - x;

                    if (IsCanMove((int) deltaX) ) {
                        if (mVelocityTracker != null) {
                            mVelocityTracker.addMovement(event);
                        }
                        mLastMotionX = x;
                        //正向或者负向移动，屏幕跟随手指移动
                        scrollBy((int) deltaX, 0);
                    }
                    break;

                case MotionEvent.ACTION_UP:
                    Log.i(TAG, "onTouchEvent  ACTION_UP " + mCurrentScreen);
                    int velocityX = 0;
                    if (mVelocityTracker != null) {
                        mVelocityTracker.addMovement(event);
                        mVelocityTracker.computeCurrentVelocity(1000);
                        //得到X轴方向手指移动速度
                        velocityX = (int) mVelocityTracker.getXVelocity();
                    }
                    //velocityX为正值说明手指向右滑动，为负值说明手指向左滑动
                    if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {
                        // Fling enough to move left
                        Log.e(TAG, "snap left");
                        snapToScreen(mCurrentScreen - 1);
                    } else if (velocityX < -SNAP_VELOCITY
                            && mCurrentScreen < getChildCount() - 1) {
                        // Fling enough to move right
                        Log.e(TAG, "snap right");
                        snapToScreen(mCurrentScreen + 1);
                    } else {
                        snapXBack();
                    }
                    if (mVelocityTracker != null) {
                        mVelocityTracker.recycle();
                        mVelocityTracker = null;
                    }
                    break;
            }
        } else {
            Log.d(TAG, "is locked");
        }
        return true;
    }

    private boolean IsCanMove(int deltaX) {
        //deltaX<0说明手指向右划
        if (getScrollX() <= 0 && deltaX < 0) {
            return false;
        }
        //deltaX>0说明手指向左划
        if (getScrollX() >= (getChildCount() - 1) * getWidth() && deltaX > 0) {
            return false;
        }
        return true;
    }

    public void setLock(boolean isLocked) {
        Log.d(TAG, "Lock is " + isLocked);
        mIsLocked = isLocked;
    }

    public void setOnViewChangeListener(OnViewChangeListener listener) {
        mOnViewChangeListener = listener;
    }

    public interface OnViewChangeListener {
        public void onViewChange(int view);
    }
}
